﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Drawing;

namespace Deferred.Editor.Gui
{
    public partial class ContentChooserWindow : Form
    {
        private ImageList icons = new ImageList();
        private List<TreeNode> originalNodes = new List<TreeNode>();

        public string SelectedFile { get { return contentTreeView.SelectedNode.Name; } }
        public string SelectedFileWithoutExtension { get { return SelectedFile.Remove(SelectedFile.LastIndexOf('.')); } }
        public List<string> ContentItemPaths { get; set; }
        public List<string> ValidExtensions { get; set; }
        public string BaseDirectory { get; set; }
        public bool AllowNewDirectoriesAndFiles { get; set; }

        public ContentChooserWindow()
        {
            InitializeComponent();

            Shown += new EventHandler(ContentChooserWindow_Shown);
        }

        void ContentChooserWindow_Shown(object sender, EventArgs e)
        {
            contentTreeView.Nodes.Clear();
            originalNodes.Clear();
            if (ContentItemPaths != null)
            {
                foreach (string path in ContentItemPaths)
                {
                    if (MatchesAnyExtension(path, ValidExtensions)) AddPath(path, ValidExtensions);
                }
                contentTreeView.ImageList = icons;
            }
        }

        public void AddPath(string path, List<string> validExtensions)
        {
            TreeNodeCollection currentNodeList = contentTreeView.Nodes;
            string[] pathParts = path.Split(Path.DirectorySeparatorChar);
            string pathSoFar = "";

            for (int i = 0; i < pathParts.Length; i++)
            {
                pathSoFar = Path.Combine(pathSoFar, pathParts[i]);
                if (Path.HasExtension(pathParts[i]))
                {
                    if (MatchesAnyExtension(pathParts[i], validExtensions))
                    {
                        TreeNode newNode = currentNodeList.Add(pathSoFar, pathParts[i]);
                        newNode.ImageIndex = icons.Images.Count;
                        newNode.SelectedImageIndex = icons.Images.Count;
                        icons.Images.Add(ShellIcon.GetSmallIcon(Path.Combine(BaseDirectory, pathSoFar)));
                        originalNodes.Add(newNode);
                    }
                }
                else if (currentNodeList.ContainsKey(pathParts[i]))
                {
                    currentNodeList = currentNodeList[pathParts[i]].Nodes;
                }
                else
                {
                    TreeNode newNode = currentNodeList.Add(pathSoFar, pathParts[i]);
                    currentNodeList = newNode.Nodes;
                    newNode.ImageIndex = icons.Images.Count;
                    newNode.SelectedImageIndex = icons.Images.Count;
                    icons.Images.Add(ShellIcon.GetSmallIcon(Path.Combine(BaseDirectory, pathSoFar)));
                    originalNodes.Add(newNode);
                }
            }
        }

        private bool MatchesAnyExtension(string path, List<string> validExtensions)
        {
            return validExtensions.Contains(Path.GetExtension(path)) || validExtensions.Contains(Path.GetExtension(path).Substring(1));
        }

        private void contentTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (Path.HasExtension(contentTreeView.SelectedNode.Name))
            {
                okButton.Enabled = true;
            }
            else
            {
                okButton.Enabled = false;
            }
        }

        private void contentTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (Path.HasExtension(e.Node.Name) && e.Button == MouseButtons.Left)
            {
                contentTreeView.SelectedNode = e.Node;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void contentTreeView_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right && AllowNewDirectoriesAndFiles)
            {
                contentTreeView.SelectedNode = contentTreeView.GetNodeAt(e.X, e.Y);
                if (Path.HasExtension(contentTreeView.SelectedNode.Name))
                {
                    addDirectoryToolStripMenuItem.Visible = false;
                    addFileToolStripMenuItem.Visible = false;
                    if (!originalNodes.Contains(contentTreeView.SelectedNode))
                    {
                        renameToolStripMenuItem.Visible = true;
                        deleteToolStripMenuItem.Visible = true;
                    }
                    contextMenuStrip.Show(contentTreeView, e.X, e.Y);
                }
                else
                {
                    addDirectoryToolStripMenuItem.Visible = true;
                    addFileToolStripMenuItem.Visible = true;
                    if (!originalNodes.Contains(contentTreeView.SelectedNode))
                    {
                        renameToolStripMenuItem.Visible = true;
                        deleteToolStripMenuItem.Visible = true;
                    }
                    contextMenuStrip.Show(contentTreeView, e.X, e.Y);
                }
            }
        }

        private void addDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string path = Path.Combine(contentTreeView.SelectedNode.Name, "NewDirectory");
            TreeNode newNode = contentTreeView.SelectedNode.Nodes.Add(path, "NewDirectory");
            newNode.ImageIndex = icons.Images.Count;
            newNode.SelectedImageIndex = icons.Images.Count;
            icons.Images.Add(ShellIcon.GetSmallIcon(Path.Combine(BaseDirectory, path)));
        }

        private void addFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string fileName;
            if (ValidExtensions[0].StartsWith("."))
            {
                fileName = "NewFile" + ValidExtensions[0];
            }
            else
            {
                fileName = "NewFile." + ValidExtensions[0];
            }
            string path = Path.Combine(contentTreeView.SelectedNode.Name, fileName);
            TreeNode newNode = contentTreeView.SelectedNode.Nodes.Add(path, fileName);
            newNode.ImageIndex = icons.Images.Count;
            newNode.SelectedImageIndex = icons.Images.Count;
            icons.Images.Add(ShellIcon.GetSmallIcon(Path.Combine(BaseDirectory, path)));
        }

        private void renameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            contentTreeView.SelectedNode.BeginEdit();
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            contentTreeView.Nodes.Remove(contentTreeView.SelectedNode);
        }
    }
}
